package com.sxt.controller;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.sxt.domain.File;
import com.sxt.domain.Folder;
import com.sxt.service.FileService;
import com.sxt.service.FolderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.util.List;

/**
 * @Description: 文件控制类
 */
@Controller
@RequestMapping("file")
public class FileController {
    @Autowired
    private FileService fileService;

    @Autowired
    private FolderService folderService;

    /**
     * 分页查询文件
     *
     * @param model
     * @param keyWord
     * @param page
     * @return
     */
    @RequestMapping("page.do")
    public String page(Model model, @RequestParam(defaultValue = "") String keyWord, @RequestParam(defaultValue = "1") Integer page) {
        model.addAttribute("page", page);
        // 如果关键字有数据  则放入到容器 便于页面数据回显
        if (StrUtil.isNotBlank(keyWord)) {
            model.addAttribute("keyWord", keyWord);
        }
        PageInfo<File> filePageInfo = this.fileService.queryPage(keyWord, page);
        model.addAttribute("data", filePageInfo);
        return "/view/file/list.jsp";
    }

    /**
     * 去文件上传的页面
     *
     * @param model
     * @return
     */
    @RequestMapping("toAdd.do")
    public String toAdd(Model model) {
        // 查询所有的文件夹
        List<Folder> folders = this.folderService.queryFolders();
        model.addAttribute("folders", folders);
        return "/view/file/add.jsp";
    }

    /**
     * 处理文件上传
     *
     * @return
     */
    @RequestMapping("upload.do")
    public String upload(@RequestParam("file") MultipartFile[] files, Integer folderId) {
        this.fileService.save(files, folderId);
        return "redirect:/file/page.do";
    }

    /**
     * 文件下载
     *
     * @param fileId
     * @param response
     * @throws Exception
     */
    @RequestMapping("download.do")
    public void download(Integer fileId, HttpServletResponse response) throws Exception {
        File file = this.fileService.queryFile(fileId);
        // 文件的物理路径
        String filePath = file.getFilePath();
        // 使用输入流读取文件
        FileInputStream fis = new FileInputStream(filePath);
        byte[] b = new byte[1024];
        int len = -1;
        ServletOutputStream os = response.getOutputStream();
        // 文件在下载时 由于浏览器默认支持一些文件可以解析
        // 所以要在响应头中设置浏览器处理数据的方式
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        // 在响应头中设置文件的名称
        // Content-Disposition: form-data; name="file"; filename="default.jpg"
        // 中文名称在下载时会出现乱码 需要将名称进行编码
        String name = URLEncoder.encode(file.getOldName(), "UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + name);
        // 使用输出流输出文件
        while ((len = fis.read(b)) != -1) {
            os.write(b, 0, len);
            os.flush();
        }
        os.close();
        fis.close();
    }

    /**
     * 查看图片
     *
     * @param fileId
     * @param response
     * @throws Exception
     */
    @RequestMapping("show.do")
    public void show(Integer fileId, HttpServletResponse response) throws Exception {
        File file = fileService.queryFile(fileId);
        // 文件的物理路径
        String filePath = file.getFilePath();
        // 使用输入流读取文件
        FileInputStream fis = new FileInputStream(filePath);
        byte[] b = new byte[1024];
        int len = -1;
        ServletOutputStream os = response.getOutputStream();
        // 文件在下载时 浏览器默认支持一些文件可以解析
        // 使用输出流输出文件
        while ((len = fis.read(b)) != -1) {
            os.write(b, 0, len);
            os.flush();
        }
        os.close();
        fis.close();
    }

    /**
     * 删除
     *
     * @param fileId
     * @throws Exception
     */
    @RequestMapping("delete.do")
    public String delete(Integer fileId) {
        this.fileService.delete(fileId);
        return "redirect:/file/page.do";
    }
}
